package models

import (
	"errors"
	"fmt"
	"github.com/golang-module/carbon/v2"
	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
)

// Code 验证码表
type Code struct {
	Model
	Ip      string `json:"ip" gorm:"type:varchar(100);not null; comment:'ip地址'"`
	Mobile  string `json:"mobile"  gorm:"type:varchar(100);not null; comment:'手机号码'"`
	Code    string `json:"codeService"  gorm:"type:varchar(100);not null; comment:'验证码'"`
	EndTime int64  `json:"end_time"  gorm:"type:int;not null; comment:'截止时间'"`
	IsCheck int8   `json:"is_check"  gorm:"type:int; comment:'是否校验 1已校验'"`
	Type    int16  `json:"type"  gorm:"type:int;not null; comment:'类型 1代理端app注册'"`
}

// ExistCodeByMobile 通过mobile判断是否存在
func ExistCodeByMobile(codeStr string, mobile string) (bool, error) {
	var code *Code
	err := db.Model(&code).Where("mobile = ? AND codeService = ? AND is_check <> 1", mobile, codeStr).First(&code).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		logrus.WithError(err).Errorf("查询验证码失败 codeService: %s, mobile: %s err:%v", codeStr, mobile, err)
		return false, fmt.Errorf("无效的验证码")
	}

	if carbon.Now().Timestamp() > code.EndTime {
		return false, fmt.Errorf("验证码已过期")
	}

	return true, nil
}

// GetCodeCount 获取未使用验证码数量
func GetCodeCount(mobile string, typed int16) int64 {
	var count int64
	db.Model(&Code{}).Where("mobile = ? AND type = ? AND is_check <> 1 AND end_time > ?", mobile, typed, carbon.Now().Timestamp()).Count(&count)
	return count
}

// UpdateCodeIsCheck 更新验证码状态
func UpdateCodeIsCheck(code string) error {
	err := db.Model(&Code{}).Where("codeService = ?", code).Update("is_check", 1).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		logrus.WithError(err).Errorf("更新验证码状态失败 codeService: %s err:%v", code, err)
		return fmt.Errorf("更新验证码状态失败")
	}

	return nil
}

// AddCode 添加验证码
func AddCode(ip string, mobile string, code string, typed int16) error {
	err := db.Create(&Code{
		Ip:      ip,
		Mobile:  mobile,
		Code:    code,
		Type:    typed,
		IsCheck: 0,
		EndTime: carbon.Now().AddMinutes(10).Timestamp(),
	}).Error

	if err != nil {
		logrus.WithError(err).Errorf("添加验证码失败 ip: %s, mobile: %s, codeService: %s, typed: %d err:%v", ip, mobile, code, typed, err)
		return fmt.Errorf("添加验证码失败")
	}
	return nil
}
